package helper

import (
    "crypto/md5"
    "crypto/sha1"
    "crypto/sha256"
    "crypto/sha512"
    "encoding/base64"
    "encoding/hex"
    "fmt"
    "hash"
    "io"
    "os"
    "strconv"
    "strings"
    "time"
    
    "golang.org/x/crypto/bcrypt"
)

// GeneratePassword 明文密码生成哈希密文
func GeneratePassword(password string) (hash string, err error) {
    hashByte, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
    if err != nil {
        hash = ""
        return
    }
    hash = string(hashByte)
    return
}

// VerifyHashed 比对密码
func VerifyHashed(password string, hashStr string) error {
    return bcrypt.CompareHashAndPassword([]byte(hashStr), []byte(password))
}

// GenerateToken 生成唯一性令牌
func GenerateToken(userId string, tokenType string) string {
    var token string
    if len(tokenType) == 0 {
        tokenType = "access_token"
    }
    nowTime := time.Now().UnixNano()
    str := strconv.Itoa(int(nowTime)) + "_" + userId
    if "access_token" == tokenType {
        md5Hashed := md5.Sum([]byte(str))
        // 将[]byte转成16进制
        token = fmt.Sprintf("%x", md5Hashed)
    } else {
        h := sha1.New()
        tokenHex := string(h.Sum([]byte(str)))
        token = base64.StdEncoding.EncodeToString([]byte(tokenHex))
    }
    return "collecter-" + token
}

/*// VerifyToken 验证 token 有效性
func VerifyToken(token string) bool {
	res := Cacher.Get(token)
	if res == nil {
		return false
	}
	tokenBytes := res.([]byte)
	// fmt.Println(res)
	return string(tokenBytes) == token
}*/

// GenerateFileUUID 生成文件指纹（UUID）
func GenerateFileUUID(filename string, hashType string) string {
    var hashStr string
    var hashObj hash.Hash
    file, err := os.Open(filename)
    defer func() {
        _ = file.Close()
    }()
    if err != nil {
        panic("生成文件指纹（UUID）失败： " + err.Error())
    }
    
    switch strings.ToLower(hashType) {
    case "md5":
        hashObj = md5.New()
    case "sha256":
        hashObj = sha256.New()
    case "sha512":
        hashObj = sha512.New()
    case "sha1":
        hashObj = sha1.New()
    }
    if _, err := io.Copy(hashObj, file); err != nil {
        panic("生成文件指纹（UUID）失败： " + err.Error())
    }
    hashBytes := hashObj.Sum(nil)
    
    if "md5" == hashType {
        hashStr = hex.EncodeToString(hashBytes)
    } else {
        hashStr = string(hashBytes)
    }
    return hashStr
}
